<!-- 个人主页文章信息 -->
<template>
  <div class="grid m-0 p-0" ref="centreDetail">
    <!-- 统计专栏 -->
    <div class="col-12">
      <DataView @page="detailPagingHandler"
                :value="detailPaginatorResult.data"
                :totalRecords="detailPaginatorResult.total"
                :layout="layout"
                :paginator="hasPaginator"
                :rows="detailPaging.limit">
        <template #empty>
          <div class="grid">
            <div class="col-12 flex justify-content-center align-content-center m-5">
              <svg viewBox="0 0 1024 1024"
                   xmlns="http://www.w3.org/2000/svg" width="256" height="256">
                <path
                    d="M855.930143 390.219399 520.426927 220.999346 623.978351 94.302783c5.387707-6.592139 14.685467-8.455579 22.197558-4.447289L945.015088 249.306043c9.958816 5.313006 12.535501 18.426675 5.328355 27.113521L855.930143 390.219399 855.930143 390.219399zM415.439804 94.525863l99.281167 126.4786L182.193529 390.219399 82.559321 273.774317c-7.486508-8.750291-4.838192-22.196535 5.408173-27.453259L393.277038 89.671299C400.874063 85.773526 410.16773 87.808882 415.439804 94.525863zM509.37215 549.57478l-56.830333 160.529113c-1.352811 3.820002-5.750981 5.585205-9.368368 3.76065L131.658575 554.153052c-5.16565-2.605338-7.543813-8.68173-5.517667-14.101159l55.812143-149.306514L509.37215 549.57478 509.37215 549.57478zM506.779092 612.285031 506.779092 906.759809c0 3.888564-4.033873 6.465249-7.562233 4.830005L171.387415 757.291612c-6.221702-2.882654-10.183943-9.135054-10.136871-15.992229l0.967024-140.454916c0.029676-4.295839 4.563946-7.062859 8.398274-5.124717l279.498692 144.370085c5.1503 2.603291 11.423167 0.183172 13.489222-5.204535L506.779092 612.285031zM581.904093 711.284789 527.029298 549.57478l328.900845-158.829402 62.5895 147.423631c2.359744 5.557576-0.047072 11.989055-5.475711 14.633279L587.747171 713.722304C585.462129 714.834638 582.720691 713.690582 581.904093 711.284789zM873.742834 742.890624c0 5.89629-3.419889 11.257391-8.766664 13.743002L536.828478 911.576511c-3.52836 1.64036-7.567349-0.935302-7.567349-4.826935L529.261129 612.285031l40.581254 124.105552c1.482771 4.180206 6.28617 6.123464 10.258645 4.15053l282.95849-142.617162c4.91494-2.441609 10.683317 1.133823 10.683317 6.621814L873.742834 742.890624z"
                    fill="#cdcdcd"></path>
              </svg>
            </div>
          </div>

        </template>
        <template #header>
          <div class="grid grid-nogutter">
            <div class="col-3 flex align-items-center" style="text-align: left">
              <InputText v-model="inputFilter"
                         style="width: 100%;"
                         @compositionstart="compositionstartHandler"
                         @compositionend="compositionendHandler"
                         placeholder="输入标题关键字"/>
            </div>
            <div class="col-3">
              <ChipsSelected class="p-2"
                             filter
                             style="width: 100%;"
                             placeholder="选择1个专栏"
                             @change="specialChipsSelectedChangHandler"
                             :max="1"
                             :open-add="false"
                             :items="specials"/>
            </div>
            <div class="col-3">
              <ChipsSelected class="p-2"
                             filter
                             style="width: 100%;"
                             placeholder="可选择多个标签"
                             @change="tagsChipsSelectedChangHandler"
                             :open-add="false"
                             :items="tags"/>
            </div>
            <div class="col-3 grid p-0 m-0">
              <div class="col-6 flex justify-content-end align-items-center">
                <SelectButton v-model="detailOptions"
                              :options="detailOptionsSelected"
                              multiple
                              optionLabel="value"
                              dataKey="value"
                              aria-labelledby="multiple">
                  <template #option="slotProps">
                    <i :class="slotProps.option.icon"></i>
                  </template>
                </SelectButton>
              </div>

              <div class="col-6  flex justify-content-end align-items-center">
                <DataViewLayoutOptions class="flex justify-content-end" v-model="layout"/>
              </div>
            </div>
          </div>
        </template>
        <template #list="slotProps">
          <div class="col-12">
            <div class="details-list-item" style="height: 100% !important;">
              <div class="details-list-detail">
                <div class="details-name">{{ slotProps.data.title }}</div>
                <div class="details-description">{{ slotProps.data.desc }}</div>
                <i class="pi pi-tag details-category-icon"></i>
                <span class="details-category">
                          <span v-for="(item, index) of slotProps.data.tags.split(',')" :key="index">
                            {{ item + ' ' }}
                          </span>
                        </span>
              </div>
              <div class="details-list-action">
                <router-link target="_blank" :to="{path:'/detail/' + slotProps.data.id}">
                  <Button label="浏览"/>
                </router-link>
                <span v-if="slotProps.data.special"
                      class="details-special">
                        {{ slotProps.data.special }}
                </span>
              </div>
            </div>
          </div>
        </template>
        <template #grid="slotProps">
          <div class="col-12 md:col-4 p-2">
            <div class="details-grid-item card">
              <!-- 顶部 -->
              <div class="details-grid-item-top">
                <!-- 标签 -->
                <div v-if="slotProps.data.tags">
                  <i class="pi pi-tag details-category-icon"></i>
                  <span class="details-category">
                          <span v-for="(item, index) of slotProps.data.tags.split(',')" :key="index">
                            {{ item + ' ' }}
                          </span>
                        </span>
                </div>
                <!-- 专栏 -->
                <span v-if="slotProps.data.special" class="details-special">
                        {{ slotProps.data.special }}
                </span>
              </div>
              <!-- 内容 -->
              <div class="details-grid-item-content">
                <div class="details-name">{{ slotProps.data.title }}</div>
                <div class="details-description m-text-overflow-ellipsis-3">{{ slotProps.data.desc }}</div>
              </div>
              <!-- 底部按钮 -->
              <div class="details-grid-item-bottom">
                <span class="details-number">
                  <i class="pi pi-thumbs-up"></i>
                  {{ slotProps.data.goodNumber }}
                </span>
                <span class="details-number">
                  <i class="pi pi-star"></i>
                  {{ slotProps.data.collectionNumber }}
                </span>
                <span class="details-number">
                  <i class="pi pi-comments"></i>
                  {{ slotProps.data.commentNumber }}
                </span>
                <router-link target="_blank" :to="{path:'/detail/' + slotProps.data.id}">
                  <Button label="浏览"/>
                </router-link>
              </div>
            </div>
          </div>
        </template>
      </DataView>
    </div>
  </div>
</template>

<script lang="ts" setup>
/** JS */
import {ref, reactive, Ref, onMounted, watch, onUpdated, nextTick, defineEmits} from 'vue';
import {
  SpecialService,
  DetailResponseData,
  TagService,
  DetailService,
  UserMsg,
  DetailPageInfo, PaginatorResponseResult
} from '@/utils/ApiRequest';
import {useRoute, useRouter} from 'vue-router';
import Cache from '@/utils/Cache';

/** 组件 */
import ChipsSelected from '@/components/input/ChipsSelected.vue';
import DataViewLayoutOptions from 'primevue/dataviewlayoutoptions';
import SelectButton from 'primevue/selectbutton';
import DataView from 'primevue/dataview';


const specialService = new SpecialService(),
    detailService = new DetailService(),
    tagService = new TagService(),
    cache = new Cache(),
    userMsg: UserMsg = cache.get('userMsg'),
    route = useRoute(),
    router = useRouter(),
    emits = defineEmits(['onUpdated']);

let nickname: Ref<string | string[]> = ref(route.params.nickname);

/** 布局 */
let layout = ref('grid'),
    /** 过滤筛选 */
    inputFilter = ref('');
/** 筛选输入法 */
const cnInput = ref(false), sendTime: any = ref(null)
const compositionstartHandler = () => {
      clearTimeout(sendTime.value);
      cnInput.value = true;
    },
    compositionendHandler = () => {
      detailPaging.title = inputFilter.value;
      getDetailByNickname();
      cnInput.value = false;
    }
watch(inputFilter, (n) => {
  // 输入非中文时触发
  if (!cnInput.value || n.trim() === '') {
    clearTimeout(sendTime.value);
    sendTime.value = setTimeout(() => {
      detailPaging.title = n;
      getDetailByNickname();
    }, 500);
  }
});

/** 获取专栏 */
let specials: Ref<string[]> = ref([]);
const getSpecialByNickname = async () => {
      let tempNickname;
      if (!nickname.value || (nickname.value as string).trim() === '') {
        // Nickname 不存在或者为空
        tempNickname = userMsg.nickname;
      } else {
        // Nickname 存在
        tempNickname = nickname.value as string;
      }
      let res = await specialService.getSpecialListByNickname({nickname: tempNickname});
      specials.value = res.data.map(special => special.name);
    },
    specialChipsSelectedChangHandler = async (arr: []) => {
      if (arr.length > 1) {
        arr.pop();
      }
      let specialStr = arr.join(',');
      detailPaging.title = `#${specialStr}`;
      await getDetailByNickname();
    }

/** 获取标签 */
let tags: Ref<string[]> = ref([]);
const getTagsByNickname = async () => {
      let tempNickname;
      if (!nickname.value || (nickname.value as string).trim() === '') {
        // Nickname 不存在或者为空
        tempNickname = userMsg.nickname;
      } else {
        // Nickname 存在
        tempNickname = nickname.value as string;
      }
      let res = await tagService.getTagsByNickname({nickname: tempNickname});
      tags.value = res.data;
    },
    tagsChipsSelectedChangHandler = async (arr: []) => {
      let tagsStr = arr.join(',');
      detailPaging.tags = tagsStr;
      await getDetailByNickname();
    }
/** 获取文章 */
let detailPaging: DetailPageInfo = reactive({
      page: 1,
      limit: 12
    }),
    detailPaginatorResult: Ref<PaginatorResponseResult<DetailResponseData>> | Ref<object> = ref({}),
    hasPaginator = ref(false);
watch(detailPaginatorResult, (n) => {
  let newData: PaginatorResponseResult<DetailResponseData> = n as PaginatorResponseResult<DetailResponseData>;
  hasPaginator.value = newData.totalPage > 1;
}, {deep: true})
/** 根据 nickname 获取文章 */
const getDetailByNickname = async () => {
      let paging = detailPaging;
      if (!nickname.value || (nickname.value as string).trim() === '') {
        // Nickname 不存在或者为空
        paging.nickname = userMsg.nickname;
      } else {
        // Nickname 存在
        paging.nickname = nickname.value as string;
      }
      let res = await detailService.getCentreDetail(paging);
      detailPaginatorResult.value = res.data;
      // 刷新高度
      await nextTick(() => {
        if (centreDetail.value) {
          let element = centreDetail.value as HTMLElement;
          emits('onUpdated', element);
        }
      })
    },
    /** 文章分页操作
     *
     * <p>这里的分页 detailPaginator 是被 limit 截取的，而不是动态渲染 detailPaginator
     * */
    detailPagingHandler = async (ev) => {
      if (ev.page === 0) {
        detailPaging.page = 1;
      } else {
        detailPaging.page = ev.page + 1;
      }
      let paging = detailPaging;
      if (!nickname.value || (nickname.value as string).trim() === '') {
        // Nickname 不存在或者为空
        paging.nickname = userMsg.nickname;
      } else {
        // Nickname 存在
        paging.nickname = nickname.value as string;
      }
      let res = await detailService.getCentreDetail(paging);
      let diff = ((detailPaging.page - 1) * detailPaging.limit);
      // 动态调整大小 length 使用浏览器中自带的 length，让其自动定位下标大小
      (detailPaginatorResult.value as PaginatorResponseResult<DetailResponseData>).data.length = length + diff;
      (detailPaginatorResult.value as PaginatorResponseResult<DetailResponseData>).data.splice(diff, 0, ...res.data.data);
      // 变回原来的大小
      // 刷新高度
      await nextTick(() => {
        if (centreDetail.value) {
          let element = centreDetail.value as HTMLElement;
          emits('onUpdated', element);
        }
      })
    };
/** 获取收藏、点赞文章 */
const detailOptionsSelected = [
      {icon: 'pi pi-thumbs-up', value: 1},
      {icon: 'pi pi-heart', value: 2}],
    detailOptions = ref(null);
watch(detailOptions, (n) => {
  detailPaging.page = 0;
  if (n) {
    let arr = n as any [];
    if (arr.length === 0) {
      // 清空
      delete detailPaging.good;
      delete detailPaging.collection;
    } else if (arr.length === 2) {
      // 双选
      detailPaging.good = true;
      detailPaging.collection = true;
    } else if (arr[0].value === 1) {
      // 点赞
      detailPaging.good = true;
      detailPaging.collection = false;
    } else if (arr[0].value === 2) {
      // 收藏
      detailPaging.good = false;
      detailPaging.collection = true;
    }
    getDetailByNickname();
  }

})

onMounted(() => {
  getDetailByNickname();
  getSpecialByNickname();
  getTagsByNickname();
})

const centreDetail = ref(null);
onUpdated(() => {
  nextTick(() => {
    if (centreDetail.value) {
      let element = centreDetail.value as HTMLElement;
      emits('onUpdated', element);
    }
  })
})
</script>

<style lang="less" scoped>
.card {
  background: #ffffff;
  padding: 2rem;
  box-shadow: 0 2px 1px -1px rgba(0, 0, 0, .2), 0 1px 1px 0 rgba(0, 0, 0, .14), 0 1px 3px 0 rgba(0, 0, 0, .12);
  border-radius: 4px;
  margin-bottom: 2rem;
}

.p-dropdown {
  width: 14rem;
  font-weight: normal;
}

.details-name {
  font-size: 1.5rem;
  font-weight: 700;
}

.details-description {
  margin: 1rem 0 1rem 0;
}

.details-category-icon {
  vertical-align: middle;
  margin-right: .5rem;
}

.details-category {
  font-weight: 600;
  vertical-align: middle;
}

.details-special {
  background: #feedaf;
  color: #8a5340;
  border-radius: 2px;
  padding: .25em .5rem;
  text-transform: uppercase;
  font-weight: 700;
  font-size: 12px;
  letter-spacing: .3px;
  text-align: center;
}

::v-deep(.details-list-item) {
  height: 100% !important;
  display: flex;
  align-items: center;
  padding: 1rem;
  width: 100%;

  img {
    width: 50px;
    box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16), 0 3px 6px rgba(0, 0, 0, 0.23);
    margin-right: 2rem;
  }

  .details-list-detail {
    flex: 1 1 0;
  }

  .p-rating {
    margin: 0 0 .5rem 0;
  }

  .details-number {
    font-size: 1.5rem;
    font-weight: 600;
    margin-bottom: .5rem;
    align-self: flex-end;
  }

  .details-list-action {
    display: flex;
    flex-direction: column;
    padding-top: 5rem;
  }

  .p-button {
    margin-bottom: .5rem;
  }
}

::v-deep(.details-grid-item) {
  height: 100% !important;
  margin: .5rem;
  border: 1px solid var(--surface-border);

  .details-grid-item-top,
  .details-grid-item-bottom {
    display: flex;
    align-items: center;
    justify-content: space-between;
  }

  .details-grid-item-bottom {
    padding-top: 2.5rem;
  }

  img {
    box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16), 0 3px 6px rgba(0, 0, 0, 0.23);
    margin: 2rem 0;
  }

  .details-grid-item-content {
    margin-top: 2.5rem;
    text-align: center;
  }

  .details-number {
    font-size: 1.5rem;
    font-weight: 600;
  }
}

@media screen and (max-width: 576px) {
  .details-list-item {
    padding: 5px !important;
    flex-direction: column;
    align-items: center;
    height: 100% !important;

    img {
      margin: 2rem 0;
    }

    .details-list-detail {
      text-align: center;
    }

    .details-number {
      align-self: center;
    }

    .details-list-action {
      display: flex;
      flex-direction: column;
      padding-top: 5rem;
    }

    .details-list-action {
      padding-top: 5rem;
      flex-direction: row;
      justify-content: space-between;
      align-items: center;
      width: 100%;
    }
  }
}
</style>
